/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package com.icee.myth.server.social;

import com.icee.myth.log.GameLogger;
import com.icee.myth.log.message.FileDebugGameLogMessage;
import com.icee.myth.log.message.builder.GameLogMessageBuilder;
import com.icee.myth.server.GameServer;
import com.icee.myth.server.levelup.HumanLevelsConfig;
import com.icee.myth.utils.Consts;
import java.util.HashMap;
import java.util.Iterator;
import java.util.LinkedList;
import java.util.TreeMap;

/**
 * 玩家简略信息容器
 * @author liuxianke
 */
public class BriefPlayerInfos {

    private final HashMap<Integer, BriefPlayerInfo> playerId2InfoMap;
    private final BriefPlayerInfosOfLevel[] briefPlayerInfosOfLevels;   // 等级对应的玩家简略信息
    private long lastRefreshTime;

    public BriefPlayerInfos() {
        playerId2InfoMap = new HashMap<Integer, BriefPlayerInfo>();

        briefPlayerInfosOfLevels = new BriefPlayerInfosOfLevel[HumanLevelsConfig.INSTANCE.maxLevel];
        for (int i = 0; i < HumanLevelsConfig.INSTANCE.maxLevel; i++) {
            briefPlayerInfosOfLevels[i] = new BriefPlayerInfosOfLevel();
        }
    }

    public void init(long curTime) {
        lastRefreshTime = curTime;
    }

    public BriefPlayerInfo get(int playerId) {
        BriefPlayerInfo briefPlayerInfo = playerId2InfoMap.get(playerId);

        if (briefPlayerInfo != null) {
            briefPlayerInfo.lastVisitTime = GameServer.INSTANCE.getCurrentTime();
        }

        return briefPlayerInfo;
    }

    public void addAll(LinkedList<BriefPlayerInfo> briefPlayerInfos) {
        for (BriefPlayerInfo briefPlayerInfo : briefPlayerInfos) {
            BriefPlayerInfo tmpBriefPlayerInfo = playerId2InfoMap.get(briefPlayerInfo.id);
            if (tmpBriefPlayerInfo != null) {
                briefPlayerInfo.inGame = tmpBriefPlayerInfo.inGame;
            } else {
                briefPlayerInfo.inGame = false;
                briefPlayerInfo.lastVisitTime = GameServer.INSTANCE.getCurrentTime();

                playerId2InfoMap.put(briefPlayerInfo.id, briefPlayerInfo);

                // 加入等级表
                briefPlayerInfosOfLevels[briefPlayerInfo.level - 1].addBriefPlayerInfo(briefPlayerInfo);
            }
        }
    }

    public void addBriefPlayerInfo(int playerId, String name, int level, int leaderCardId, int leaderCardLevel, boolean inGame) {
        BriefPlayerInfo briefPlayerInfo = playerId2InfoMap.get(playerId);

        if (briefPlayerInfo == null) {
            briefPlayerInfo = new BriefPlayerInfo(playerId, name, level, leaderCardId, leaderCardLevel);
            briefPlayerInfo.inGame = inGame;
            briefPlayerInfo.lastVisitTime = GameServer.INSTANCE.getCurrentTime();

            playerId2InfoMap.put(playerId, briefPlayerInfo);

            // 加入等级表
            briefPlayerInfosOfLevels[briefPlayerInfo.level - 1].addBriefPlayerInfo(briefPlayerInfo);
        } else {
            GameLogger.getlogger().log(GameLogMessageBuilder.buildFileDebugGameLogMessage(
                    FileDebugGameLogMessage.DebugLogType.DEBUGLOGTYPE_ERROR,
                    "Add brief player["+playerId+"] info error because info already exist."));
        }
    }

    public boolean setOffGame(int playerId) {
        BriefPlayerInfo briefPlayerInfo = playerId2InfoMap.get(playerId);

        if (briefPlayerInfo != null) {
            briefPlayerInfo.inGame = false;
            briefPlayerInfo.lastVisitTime = GameServer.INSTANCE.getCurrentTime();
            return true;
        }

        return false;
    }

    public boolean setInGame(int playerId) {
        BriefPlayerInfo briefPlayerInfo = playerId2InfoMap.get(playerId);

        if (briefPlayerInfo != null) {
            briefPlayerInfo.inGame = true;
            briefPlayerInfo.lastVisitTime = GameServer.INSTANCE.getCurrentTime();
            return true;
        }

        return false;
    }

    public boolean setPlayerLeaderCard(int playerId, int id, int level) {
        BriefPlayerInfo briefPlayerInfo = playerId2InfoMap.get(playerId);

        if (briefPlayerInfo != null) {
            briefPlayerInfo.leaderCardId = id;
            briefPlayerInfo.leaderCardLevel = level;
            return true;
        }

        return false;
    }

    // 注意：只有在线玩家升级时才调用levelupPlayer方法，因此调用时表中肯定有玩家的BriefPlayerInfo对象
    public void levelupPlayer(int playerId, int lv) {
        BriefPlayerInfo briefPlayerInfo = playerId2InfoMap.get(playerId);

        // 从原等级表中删除玩家，并加入新等级表中
        briefPlayerInfosOfLevels[briefPlayerInfo.level - 1].removeBriefPlayerInfo(briefPlayerInfo);
        briefPlayerInfo.level = lv;
        briefPlayerInfosOfLevels[briefPlayerInfo.level - 1].addBriefPlayerInfo(briefPlayerInfo);
    }

    // 定期清理（五分钟清理一次，将不在线的过期玩家简略信息从内存简略信息表中清除）
    public void refresh(long curTime) {
        if (curTime - lastRefreshTime >= Consts.MILSECOND_5MINITE) {
            lastRefreshTime = curTime;
            for (Iterator<BriefPlayerInfo> itor = playerId2InfoMap.values().iterator(); itor.hasNext();) {
                BriefPlayerInfo briefPlayerInfo = itor.next();

                if (!briefPlayerInfo.inGame && (curTime - briefPlayerInfo.lastVisitTime >= Consts.CLEAR_BRIEF_PLAYERINFO_TIME)) {
                    // 删除过期数据
                    itor.remove();

                    // 从等级表中删除
                    briefPlayerInfosOfLevels[briefPlayerInfo.level - 1].removeBriefPlayerInfo(briefPlayerInfo);
                }
            }
        }
    }

    public void getStrangers(int level, int playerId, TreeMap<Integer, Long> friends, LinkedList<BriefPlayerInfo> strangers) {
        for (int i = 0; i < 6; i++) {
            if (i == 0) {
                if (briefPlayerInfosOfLevels[level - 1].getBriefPlayerInfos(playerId, friends, strangers)) {
                    return;
                }
            } else {
                if ((level + i <= HumanLevelsConfig.INSTANCE.maxLevel) && briefPlayerInfosOfLevels[level - 1 + i].getBriefPlayerInfos(playerId, friends, strangers)) {
                    return;
                }
                if ((level - i > 0) && briefPlayerInfosOfLevels[level - 1 - i].getBriefPlayerInfos(playerId, friends, strangers)) {
                    return;
                }
            }
        }
    }
}
